﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Core.DataAccess.IRepositories;
using System.ComponentModel.Composition;

namespace Core.DataAccess.Repositories
{
    [Export(typeof(IFriendRepository))]
    public class FriendRepository : IFriendRepository
    {
        private Connection conn;
        public FriendRepository()
        {
            conn = new Connection();
        }

        public List<Friend> GetFriendsByAccountID(Int32 accountID)
        {
            List<Friend> result = new List<Friend>();
            using (MXHEntities context= conn.GetContext())
            {
                var friends = (from n in context.Friends
                                where n.AccountID == accountID || n.MyFriendsAccountID == accountID
                                select n).Distinct();
                if(friends != null)
                    result = friends.ToList();

            } 
            return result;
        }

        public List<FriendsProfile> GetFriendsAccountByAccountID(int accountID)
        {
            List<FriendsProfile> lstFriendsProfile = new List<FriendsProfile>();

            // Get friends
            List<Friend> lstFriend = this.GetFriendsByAccountID(accountID);
            if (lstFriend.Count > 0)
            {
                List<int> lstFriendsID = new List<int>();                
                lstFriend.ForEach(n => lstFriendsID.Add(n.AccountID == accountID ? n.MyFriendsAccountID : n.AccountID));

                // Get friends of my friends
                lstFriendsID.ForEach(n => lstFriend.AddRange(this.GetFriendsByAccountID(n)));                
                lstFriend = lstFriend.GroupBy(n => new {n.AccountID,n.MyFriendsAccountID }).Select(m => m.First()).ToList();
                lstFriendsID.Clear();

                // Get all id friends in lstFriends
                foreach (Friend fr in lstFriend)
                {
                    lstFriendsID.Add(fr.AccountID);
                    lstFriendsID.Add(fr.MyFriendsAccountID);
                }
                lstFriendsID = lstFriendsID.Distinct().ToList();
                using(MXHEntities context = conn.GetContext())
                {                    
                    foreach (int id in lstFriendsID)
                    {
                        var check = from fr in context.Friends
                                    where (fr.AccountID == accountID && fr.MyFriendsAccountID == id) ||
                                          (fr.AccountID == id && fr.MyFriendsAccountID == accountID)
                                    select fr;
                        if (check.Count() > 0)
                        {
                            var item = from acc in context.Accounts
                                       where acc.AccountID == id
                                       select new FriendsProfile
                                       {
                                           AccountID = acc.AccountID,
                                           FullName = acc.LastName + " " + acc.MidName + " " + acc.FirstName,                                           
                                           IsFriend = true
                                       };
                            if (item.Count() > 0)
                                lstFriendsProfile.Add(item.FirstOrDefault());
                        }
                        else
                        {
                            var item = from acc in context.Accounts
                                       where acc.AccountID == id
                                       select new FriendsProfile
                                       {
                                           AccountID = acc.AccountID,
                                           FullName = acc.LastName + " " + acc.MidName + " " + acc.FirstName,                                           
                                           IsFriend = false
                                       };
                            if (item.Count() > 0)
                            {
                                FriendsProfile fri = item.FirstOrDefault();
                                if (fri.AccountID == accountID)
                                    fri.IsFriend = true;
                                lstFriendsProfile.Add(fri);
                            }
                        }
                    }
                }
            }
            return lstFriendsProfile;
        }

        //public List<FriendsProfile> GetFriendsAccountByAccountID(int accountID)
        //{
        //    List<Friend> friends = this.GetFriendsByAccountID(accountID);

        //    List<FriendsProfile> result = new List<FriendsProfile>();
        //    //if (friends.Count > 0)
        //    //{
        //        List<int> friendsAccountIDList = new List<int>();
        //        friendsAccountIDList.Add(accountID);
        //        foreach (Friend friend in friends)
        //        {
        //            friendsAccountIDList.Add(friend.MyFriendsAccountID);
        //        }
                
        //        using (MXHEntities context = conn.GetContext())
        //        {
        //            //danh sach account la tat ca (ko phai la ban be) -- co moi lien he
        //            IEnumerable<FriendsProfile> AccountNotFriends = from n in context.Accounts
        //                                                   where !friendsAccountIDList.Contains(n.AccountID) && n.EmailVerified == true
        //                                                   select new FriendsProfile
        //                                                   {
        //                                                       AccountID = n.AccountID,
        //                                                       BirthDate = n.BirthDate.Value,
        //                                                       FullName = string.IsNullOrEmpty(n.FirstName) ? ""
        //                                                           : string.IsNullOrEmpty(n.MidName) ? n.FirstName + " "
        //                                                           : string.IsNullOrEmpty(n.LastName) ? n.FirstName + " " + n.MidName + ""
        //                                                           : n.LastName + " " + n.MidName + " " + n.FirstName,
        //                                                       CreateDateStatus = n.CreateDate.Value,
        //                                                       IsFriend = false
        //                                                   };
        //            //danh sach account la ban be
        //            IEnumerable<FriendsProfile> AccountIsFriends = from n in context.Accounts
        //                                            where friendsAccountIDList.Contains(n.AccountID) && n.EmailVerified == true
        //                                            select new FriendsProfile
        //                                            {
        //                                                AccountID = n.AccountID,
        //                                                BirthDate = n.BirthDate.Value,
        //                                                FullName = string.IsNullOrEmpty(n.FirstName) ? ""
        //                                                    : string.IsNullOrEmpty(n.MidName) ? n.FirstName + " "
        //                                                    : string.IsNullOrEmpty(n.LastName) ? n.FirstName + " " + n.MidName + ""
        //                                                    : n.LastName + " " + n.MidName + " " + n.FirstName,
        //                                                CreateDateStatus = n.CreateDate.Value,
        //                                                IsFriend = true
        //                                            };

        //            result = AccountNotFriends.Concat(AccountIsFriends).ToList();
        //        }            
        //    return result;
        //}

        public void AddFriendByAccountID(Friend friend)
        {
            using (MXHEntities context =conn.GetContext())
            {
                context.Friends.AddObject(friend);
                context.SaveChanges();
            }
        }

        public void DeleteFriendByAccountID(int accountID, int friendID)
        {
            using (MXHEntities context = conn.GetContext())
            {
                var item = from fr in context.Friends
                           where (fr.AccountID == accountID && fr.MyFriendsAccountID == friendID) ||
                                 (fr.MyFriendsAccountID == accountID && fr.AccountID == friendID)
                           select fr;
                if (item.Count() > 0)
                {
                    Friend friend = item.FirstOrDefault();
                    context.Friends.DeleteObject(friend);
                    context.SaveChanges();
                }
            }
        }        
    }
}
